package yt.demo.appcommontools.utils;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.xdb.Searcher;
import java.io.InputStream;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
public class Ip2RegionUtils {

    // 使用双重检查锁，保证线程安全
    private static volatile Searcher searcher;
    private static final Lock lock = new ReentrantLock();

    //DB路径
    private static final String DB_PATH = "ipdb/ip2region.xdb";

    // 本地网络 IP 直接返回
    private static final String LOCAL_IP = "127.0.0.1";
    private static final String LOCAL_NETWORK_PREFIX = "192.168";



    /**
     * 获取IP地址的归属地信息
     * @param ip 待查询的IP地址
     * @return 归属地信息
     */
    public static String getIpAddress(String ip) {
        // 判断本地网络IP，不需要查询
        if (LOCAL_IP.equals(ip) || ip.startsWith(LOCAL_NETWORK_PREFIX)) {
            return "局域网";
        }

        // 延迟初始化 searcher
        if (searcher == null) {
            initializeSearcher();
        }

        // 查询 IP 地址归属地
        try {
            return searcher.search(ip);
        } catch (Exception e) {
            log.error("Error querying IP: {}", ip, e);
            throw new RuntimeException("获取IP地址异常", e);
        }
    }

    /**
     * 初始化 searcher 对象，加载数据库
     */
    private static void initializeSearcher() {
        // 双重检查锁，保证线程安全
        if (searcher == null) {
            lock.lock();  // 加锁，确保只会有一个线程进行初始化
            try {
                if (searcher == null) {
                    try (InputStream inputStream = new ClassPathResource(DB_PATH).getStream()) {
                        byte[] bytes = IoUtil.readBytes(inputStream);
                        searcher = Searcher.newWithBuffer(bytes);
                    } catch (Exception e) {
                        log.error("初始化 searcher 失败: ", e);
                        throw new RuntimeException("初始化数据库失败", e);
                    }
                }
            } finally {
                lock.unlock();  // 解锁
            }
        }
    }
}
